import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Sprite;
import flash.ui.Keyboard;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
import haxe.FastList; 
import flash.display.Shape;
import flash.events.MouseEvent;
import TextArea;
import PauseMenu;

import flash.utils.Timer;
import flash.events.TimerEvent;

//import haxe.Timer;
import flash.events.Event;


import Images;  
import Blob;
import Character;
import Sounds;

class Scene extends Sprite 
{
  public var characters  : FastList<Character>;
  public var preSceneText : FastList<TextArea>;
  public var ground : Int;
  public var rightWall : Int;
  public var leftWall : Int;
  public var currentBackground : BitmapData;
  public var blankBackground : BitmapData;
  public var text : String;
  var mKeyDown:Array<Bool>;
  var lastUp:Int;
  var Player:Character;
  var Pause:String;
  public var volume:Bool;
  public var sound:Bool;
  public var running:Bool;
  public var victory:String;
  var myTimer:Timer;
  var State:String;
  var PauseTillKeyPressed:Bool;
  var label1:TextField;
  //var labelBackground:Sprite;
  var NOButton:Sprite;
  var YesButton:Sprite;
  var textBackgroundImage:Sprite;
var swwoshSound:Swwosh; 
var biteSound:Bite; 
public var pauseMenu:PauseMenu;
var pauseMenuPoint:Point;

  public function new(inBackground:BitmapData,inText:FastList<TextArea>,inCharacters:FastList<Character>)
  {
  super();
pauseMenu = new PauseMenu();
pauseMenuPoint = new Point(0,370);
  ground = 374;
  leftWall = 0;
  rightWall = 480;
  characters = inCharacters;
  running = false;
  victory = "None";
  Pause = "UnPaused";
  volume = true;
  sound = true;
  preSceneText = new FastList<TextArea>();
  while(!inText.isEmpty()) 
  {
   var text:TextArea = null;
   text = inText.pop();
   preSceneText.add(text);
  }
  State = "CutScence"; 
 PauseTillKeyPressed = false;
 swwoshSound = new Swwosh();
 biteSound = new Bite();


 Player = null;
 for (character in characters.iterator()) 
 {
    if(character.characterType == "Main")
    {
      Player = character;
    }	

  }
  //characters.copy(inCharacters);
  currentBackground = inBackground.clone(); //new Background();
  blankBackground = inBackground.clone();
mKeyDown = [];
lastUp = Keyboard.RIGHT;
  }

//Load Level, so that it isn't automatically loaded automatically.
public function Load(inVolume:Bool,inSound:Bool)
{
  volume = inVolume;
  sound = inSound;
  running = true;
  flash.Lib.current.addChild(this);
  addChild(new Bitmap(currentBackground));
        drawCharacters(); 
  //this.addEventListener(Event.ENTER_FRAME, OnEnter)
  //On Enter Was very slow on my computer. So I'm using the timer event so it doesn't render as much.
  myTimer = new Timer(25);
  myTimer.addEventListener("timer", timerHandler);
  myTimer.start();
  stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown );
  stage.addEventListener(KeyboardEvent.KEY_UP, OnKeyUp );

}

public function PreScene()
{
   if(PauseTillKeyPressed)
     {
      return;
     }
   var text:TextArea = null;
   text = preSceneText.pop();
   if(label1 != null)
      {removeChild(label1);}
   if(textBackgroundImage != null)
      {removeChild(textBackgroundImage);}
   if(text != null)
     {  
        label1 = new TextField();
       textBackgroundImage = new Sprite();
       textBackgroundImage.graphics.beginBitmapFill(new TextBackground());
       textBackgroundImage.graphics.drawRect(0, 0, 540 ,175);
       textBackgroundImage.x = 50;
       textBackgroundImage.y = 0;
       
        label1.x = 100; label1.y = 0;
        label1.width = 440; //label1.height = 175
        addChild(textBackgroundImage);
        addChild(label1);
        label1.multiline = true;
	var myFormat:TextFormat = new TextFormat();
	//myFormat.size = 15;
	myFormat.align = TextFormatAlign.CENTER;
        label1.defaultTextFormat = myFormat;
        //Turning off for now
        label1.background = false;
        label1.backgroundColor = text.backgroundColor;
       
        label1.htmlText = text.htmlTextUnconverted;
        label1.y = ((150 - label1.height)/2);
        label1.wordWrap = true;

        label1.autoSize = TextFieldAutoSize.CENTER;
        PauseTillKeyPressed = true;
      }
   else
      {
       label1 = new TextField();
       label1.x = 300; label1.y = 75;
       label1.width = 200; label1.height = 100;
       addChild(label1);
       label1.htmlText = "<font size='25'>Give Up?</font>";
       YesButton = new Sprite();
       YesButton.graphics.beginBitmapFill(new Yes());
       YesButton.graphics.drawRect(0, 0, 150 ,48);
       YesButton.x = 280;
       YesButton.y = 125;
       YesButton.buttonMode = true;
       YesButton.addEventListener(MouseEvent.CLICK, onYesButtonClick);
       addChild(YesButton);

       NOButton = new Sprite();
       NOButton.graphics.beginBitmapFill(new NO());
       NOButton.graphics.drawRect(0, 0, 150 ,48);
       NOButton.x = 280;
       NOButton.y = 200;
       NOButton.buttonMode = true;
       NOButton.addEventListener(MouseEvent.CLICK, onNOButtonClick);
       addChild(NOButton);
       State = "Wait";
      }
      

}
private function onYesButtonClick(event:MouseEvent) {
victory = "GaveUp";
 if(label1 != null)
   {removeChild(label1);}
removeChild(YesButton);
removeChild(NOButton);
State="GaveUp";

}

private function onNOButtonClick(event:MouseEvent) {
removeChild(label1);
removeChild(YesButton);
removeChild(NOButton);
State = "Playing";
}

public function timerHandler(event:TimerEvent) {
    if(State == "CutScence")
    {
       PreScene();
    }
    else if(State == "Wait")
    {
    }
    else if(State == "Playing")
    {
    MovementPhase();
    }
    else if(State == "Victory")
    {
    unLoad();
    }
    else if(State == "Loss")
    {
    unLoad();
    }
    else if (State == "GaveUp")
    {
      unLoad();
    }
}


//Define Win
public function checkWin() : Bool
{
  var playerAlive:Bool = false;
  var enemiesDead:Bool = true;
  for (character in characters.iterator()) 
  {
  if(character.characterType == "Enemy")
    enemiesDead = false;
  if(character.characterType == "Main")
     playerAlive = true;
  }
  return(playerAlive && enemiesDead);
}

//Define Loss
public function checkLoss() : Bool
{
  var playerAlive:Bool  = false;
  for (character in characters.iterator()) 
  {
  if(character.characterType == "Main")
     playerAlive = true;
  }
  return(!playerAlive);
}
//When we're done with the level, we'll unload in.
public function unLoad()
{
  running = false;
  //removeChild(new Bitmap(currentBackground));
  myTimer.stop();
  flash.Lib.current.removeChild(this);
      for (character in characters.iterator()) 
      {
        characters.remove(character);
      }
}
public function OnKeyDown (event:KeyboardEvent)
   {

      // When a key is held down, multiple KeyDown events are generated.
      // This check means we only pick up the first one.
      if (!mKeyDown[event.keyCode])
      {
         //Press any key to continue scence
         PauseTillKeyPressed = false;
         // Store for use in game
         mKeyDown[event.keyCode] = true;
         //I do this here, because if they hold down P,
	 // it won't pause and unpause constantly.
	  if(mKeyDown[ 80 ] == true)
	  {
           if(State == "Playing")
              {
	      if(Pause == "Paused" || Pause == "Pausing")
                {
                  Pause = "UnPausing";
                }
              else 
                {
                  Pause = "Pausing";
		  pauseMenu.x = pauseMenuPoint.x;
		  pauseMenu.y = pauseMenuPoint.y;
		  addChild(pauseMenu);
                }
              }
	  }
// 	  if(mKeyDown[ 77 ] == true)
// 	  {
// 	      Mute = !Mute;
// 	  }
      }
    }
public function OnKeyUp (event:KeyboardEvent)
    {
      mKeyDown[event.keyCode] = false;
      lastUp = event.keyCode;
    }
 // This function gets called once per flash frame.
   // This will be approximately the rate specified in the swf, but usually a
   //  bit slower.  For accurate timing, we will not rely on flash to call us
   //  consistently, but we will do our own timing.
   function OnEnter(e:flash.events.Event)
   {
     //Re Draw EveryThing.
      MovementPhase();
   }

  public function clearBackground()
  {
      var byteRect = new Rectangle(0,0,blankBackground.width,blankBackground.height);
      currentBackground.copyPixels(blankBackground,byteRect,  new Point(0,0),null,null,true);
  }
  public function clearCharacters()
  {
     for (character in characters.iterator()) 
      {
      //Get Character Postion Info
      var byteRect = new Rectangle(character.postion.x,character.postion.y,character.CurrentCharacter.mRect.width,character.CurrentCharacter.mRect.height);
      var oldCharacterPoint = new Point(character.postion.x,character.postion.y);

      //Get Attack Postion
      if(character.attack != null)
      {
      var AttackByteRect = new Rectangle(character.attackPostion.x,character.attackPostion.y,character.attack.mRect.width,character.attack.mRect.height);
      var oldAttackPoint = new Point(character.attackPostion.x,character.attackPostion.y);
      
      //clear all data
      currentBackground.copyPixels(blankBackground,byteRect,  oldCharacterPoint,null,null,true);

       currentBackground.copyPixels(blankBackground,AttackByteRect, oldAttackPoint,null,null,true); 
      }
        //If they die remove them.        
        if(character.health <= 0)
        {
	  characters.remove(character);
        }
      }
  }
  public function drawCharacters()
  {
      for (character in characters.iterator()) 
      {
      currentBackground.copyPixels(character.CurrentCharacter.mBits,character.CurrentCharacter.mRect,new Point(character.postion.x,character.postion.y),null,null,true); 
      }
  }

//Pause Menu
public function addPauseMenu()
{
pauseMenu.x = pauseMenuPoint.x;
pauseMenu.y = pauseMenuPoint.y;
if(pauseMenuPoint.y <= 0)
{
Pause = "Paused";
} 
if(Pause == "Pausing")
{
 pauseMenuPoint.y = pauseMenuPoint.y - 20;
}
   
}
public function removePauseMenu()
{
pauseMenu.x = pauseMenuPoint.x;
pauseMenu.y = pauseMenuPoint.y;
if(pauseMenuPoint.y >= 380)
{
Pause = "UnPaused";
removeChild(pauseMenu);
} 
if(Pause == "UnPausing")
{
pauseMenuPoint.y = pauseMenuPoint.y + 20;
}


}

  public function MovementPhase()
  {   
      if(Pause != "UnPaused")
      {
	if(Pause == "Paused" || Pause == "Pausing")
          {
          addPauseMenu();
          }
        else if(Pause == "UnPausing")
         {
          removePauseMenu();
          }
         return;
      }
      clearCharacters();
      if(checkWin())
        {
        victory = "Victory";
        State = "Victory";
        }
      if(checkLoss())
        {
        victory = "Loss";
        State = "Loss";
        }

       for (character in characters.iterator()) 
       {

	if(character.characterType == "Main")
           {
            if(character.attacking == 1)
            {
	      if(sound)
	      {
	      swwoshSound.play();
	      }
            }
       if(mKeyDown[ Keyboard.LEFT ])
	{
	 character.MoveLeft();
	}
	if (mKeyDown[ Keyboard.RIGHT ])
	{
	  character.MoveRight();
	}
	if (mKeyDown[ Keyboard.UP ])
	{
         character.Jump();
	}
	if (mKeyDown[ Keyboard.SPACE ])
	{


	}
      }
	if(character.characterType == "Enemy")
      {
	  if(Std.random(4) == 0)
	  {
	  if(Player.postion.x < character.postion.x)
	    {
	    character.MoveLeft();
	    }
	    if (Player.postion.x >character.postion.x)
	    {
	    character.MoveRight();
	    }
	  }
	  if(Std.random(20) == 0)
	  {
	      var hitRect = new Rectangle(Player.postion.x,Player.postion.y,Player.CurrentCharacter.mRect.width,Player.CurrentCharacter.mRect.height);
	      var attackRect = new Rectangle(character.postion.x,character.postion.y,character.CurrentCharacter.mRect.width,character.CurrentCharacter.mRect.height);
	      if(hitRect.intersects(attackRect))
	       {
                  //Bite sound
		if(sound)
		{
                  biteSound.play();
		}
		  Player.hit++;
		  Player.health =  Player.health - character.attackPower;
	       }
	  }
      }
      character.Move(ground);
      character.getCharacter(mKeyDown);
      character.getAttack(mKeyDown);
      if(character.hit % 2 == 0)
      {
      currentBackground.copyPixels(character.CurrentCharacter.mBits,character.CurrentCharacter.mRect,new Point(character.postion.x,character.postion.y),null,null,true); 
      }
      if(character.hit > 0) 
      {
         character.hit++;
         if(character.hit >= 25)
	  {
	    character.hit = 0;
	  }
      }

      //draw attack
      if(character.attacking > 0)
      {
      if(character.attacking <= 10)
      {
           for (hitcharacter in characters.iterator()) 
        {
	  if(hitcharacter != character && hitcharacter.hit <= 0)
             {
	      var hitRect = new Rectangle(hitcharacter.postion.x,hitcharacter.postion.y,hitcharacter.CurrentCharacter.mRect.width,hitcharacter.CurrentCharacter.mRect.height);
	     var attackRect = new Rectangle(character.attackPostion.x,character.attackPostion.y,character.attack.mRect.width,character.attack.mRect.height);
             if(hitRect.intersects(attackRect))
             {
	       hitcharacter.health =  hitcharacter.health - character.attackPower;
               hitcharacter.hit++;
	     }
             }
        }
       } 
       if(character.attacking < 10 || character.attacking % 2 == 0)
       {
       currentBackground.copyPixels(character.attack.mBits,character.attack.mRect,new Point(character.attackPostion.x,character.attackPostion.y),null,null,true); 
       }
      }
   }
      
      //characters.stand.draw(currentBackground,50,20);	
  } 
}

